#include "network.h"

//  ​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​
//  * 初始化函数 - 建立连接并设置初始状态
//  * 关键操作：
//  * 1. 非阻塞connect
//  * 2. 超时设置
//  * 3. 初始状态配置
//  ​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​*​**​
int init_client(ClientContext *ctx, const char *ip, int port)
{
    // 创建非阻塞套接字
    ctx->sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
    if (ctx->sockfd < 0)
    {
        perror("socket");
        return -1;
    }

    // 配置服务器地址
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);

    // 连接超时机制 todo

    // 连接
    connect(ctx->sockfd, (struct sockaddr *)&addr, sizeof(addr));
    
    // 初始化状态
    ctx->state = STATE_IDLE;
    strcpy(ctx->current_dir, "/"); // 默认根目录
    return 0;
}

/* 发送协议命令（自动添加协议头）
 * 参数：
 *   ctx        - 客户端上下文
 *   cmd        - 命令类型(来自protocol.h)
 *   data       - 附加数据(如命令参数)
 *   data_len   - 数据长度
 * 工作流程：
 *   1. 填充协议头结构
 *   2. 发送协议头
 *   3. 发送附加数据(如果有) */
int send_command(ClientContext *ctx, Command cmd, const char *data, size_t data_len)
{
    protocol_header_t header = {
        .magic = MAGIC_NUMBER, // 固定魔数
        .command = cmd,
        .data_length = data_len};

    // 第一阶段：发送协议头
    if (send(ctx->sockfd, &header, HEADER_LENGTH, 0) != 0)
    {
        fprintf(stderr, "[ERROR] Failed to send header\n");
        return -1;
    }

    // 第二阶段：发送附加数据（如果有）
    if (data_len > 0 && data != NULL)
    {
        if (send(ctx->sockfd, data, data_len, 0) != 0)
        {
            fprintf(stderr, "[ERROR] Failed to send payload\n");
            return -2;
        }
    }
    return 0;
}

/* 接收协议响应（自动解析协议头）
 * 安全措施：
 * 1. 缓冲区溢出检查
 * 2. 魔数验证
 * 3. 数据长度验证 */
int receive_response(ClientContext *ctx, protocol_header_t *header,
                     char *buf, size_t buf_size)
{
    // 第一阶段：接收固定长度协议头
    if (recv(ctx->sockfd, header, HEADER_LENGTH, MSG_WAITALL) != HEADER_LENGTH)
    {
        fprintf(stderr, "[ERROR] Header receive failed\n");
        return -1;
    }

    // 魔数验证（防止错误数据）
    if (header->magic != MAGIC_NUMBER)
    {
        fprintf(stderr, "[ERROR] Invalid magic number: %X\n", header->magic);
        return -2;
    }

    // 第二阶段：接收数据体（如果有）
    if (header->data_length > 0)
    {
        // 防御：检查缓冲区是否足够
        if (header->data_length > buf_size)
        {
            fprintf(stderr, "[ERROR] Buffer too small (%zu < %d)\n",
                    buf_size, header->data_length);
            return -3;
        }
        if (recv(ctx->sockfd, buf, header->data_length, MSG_WAITALL) != header->data_length)
        {
            fprintf(stderr, "[ERROR] Payload receive failed\n");
            return -4;
        }
    }
    return 0;
}